#include "cdimmingx.h"
#include "v2/xml/xml_device_object.h"

CDimmingx::CDimmingx(QObject *parent) :
    CKnxControl(parent)
{
    curent_value = 0;
}

void CDimmingx::setKnxObject(void *xOBJECT)
{
    //表达式状态
    _onValue = "1"; _offValue = "0";
    if(!_status_true.isEmpty())
    {
        _onValue = _status_true;
    }

    if(!_status_false.isEmpty())
    {
        _offValue = _status_false;
    }
    
    _min = 0; _max = 230;

    if(!_min_value.isEmpty())
    {
        _min = _min_value.toFloat();
    }

    if(!_max_value.isEmpty())
    {
        _max = _max_value.toFloat();
    }

    if(_min < 0 ) _min = 0;
    if(_max> 255 || _max < 80) _max = 200;

    Xml_DEVICE_OBJECT *object = (Xml_DEVICE_OBJECT *)xOBJECT;

    QStringList arrys;
    object->_exp = object->_exp.trimmed();

    //发送值
    _sendOnArray = object->_send.split(",");
    _sendValueArray = object->_dim_send.split(",");

    //反馈值
    arrys = object->_status.split(",");
    if(arrys.size()>1)
    {
        QStringList feedList = arrys.at(0).split(":");
        if(feedList.size() >= 3)
        {
            _feedbackAddress = feedList.at(0);
            _feedbackDataType =  (DATA_TYPE)feedList.at(1).toUInt();
            _feedbackValueDefine =  (DATA_DEFINE)feedList.at(2).toUInt();
        }

        feedList = arrys.at(1).split(":");
        if(feedList.size() >= 3)
        {
           _feedbackDimAddress = feedList.at(0);
           _feedbackDimType =  (DATA_TYPE)feedList.at(1).toUInt();
           _feedbackDimDefine =  (DATA_DEFINE)feedList.at(2).toUInt();
        }
    }
}

void CDimmingx::readKnxAction()
{
    CKnxExecThread *eThread = new CKnxExecThread();
    eThread->ttgConnector = (CTTGIpsConnector *)cntDelegate;

    connect(eThread,SIGNAL(finished()),eThread,SLOT(deleteLater()));

    CExecStruct *s = new CExecStruct();
    s->address = _feedbackAddress.split(":")[0];
    eThread->execList.append(s);

    s = new CExecStruct();
    s->address = _feedbackDimAddress.split(":")[0];
    eThread->execList.append(s);

    eThread->start();
}

void CDimmingx::execKnxAction(QString action,QString value)
{
    qDebug() << "CDimmingx:execKnxAction  " << action + " = " + value;

    CKnxExecThread *eThread = new CKnxExecThread();
    eThread->ttgConnector = (CTTGIpsConnector *)cntDelegate;

    connect(eThread,SIGNAL(finished()),eThread,SLOT(deleteLater()));


    QString sendAddress,sendValue;
    float dim_value = 0.0;
    DATA_TYPE sendDataType;
    DATA_DEFINE sendValueDefine;

    //default value
    sendValue = value;
    dim_value = value.toFloat();

    QStringList *sendArray = &_sendOnArray;

    if(action == DEVICE_ACTION_SWITCH)
    {
        sendArray = &_sendOnArray;
    }
    else if(action == DEVICE_ACTION_DIM)
    {
        sendArray = &_sendValueArray;
        //0~1.0
        if(dim_value<0) dim_value = 0.0;
        if(dim_value>1.0) dim_value = 1.0;

        dim_value = (_max - _min)*dim_value;
    }

    for (int i=0; i<sendArray->size(); i++)
    {
        QString dev = sendArray->at(i);
        QStringList devArray = dev.split(":");

        if (devArray.size() >= 3) {
            sendAddress = devArray.at(0);

            if (sendAddress == "msleep") {
                CExecStruct *s = new CExecStruct();
                s->address = dev;

                eThread->execList.append(s);
            }
            else
            {
                sendDataType = (DATA_TYPE)devArray.at(1).toUInt();
                sendValueDefine = (DATA_DEFINE)devArray.at(2).toUInt();

                if(action == DEVICE_ACTION_SWITCH)
                {
                    QStringList sl = devArray.at(3).split("|");
                    if(sl.size() == 2)
                    {
                        if(value == DEVICE_STATUS_ON)
                        {
                            sendValue = sl.at(0);
                        }else{
                            sendValue = sl.at(1);
                        }
                    }else{
                        sendValue = devArray.at(3);
                    }
                }
                else if(action == DEVICE_ACTION_DIM)
                {
                    sendValueDefine = UNSIGNED_INT;
                    sendDataType = ONE_BYTE_VALUE;
                    sendValue = QString("%1").arg((int)dim_value);
                }

                if(!sendAddress.isEmpty())
                {
                    qDebug() << "CDimmingx:" <<  sendAddress << " = " << sendValue;

                    int data_len = 0;
                    memset(_data_buf,0,sizeof(_data_buf));

                    if((data_len = DEVICE_OBJECT::KnxQStringToData(sendValue,sendDataType,sendValueDefine,(_u8 *)_data_buf)) == -1)
                    {
                        qDebug() << "SetDev ret='-1' msg='error data args'" ;
                        continue ;
                    }

                    CExecStruct *s = new CExecStruct();
                    s->address = sendAddress;
                    s->type = sendDataType;
                    s->data = QByteArray((const char *)_data_buf,data_len);

                    eThread->execList.append(s);
                }
            }
        }

    }

    eThread->start();

}

QString CDimmingx::actionFromStatus(QString address,QString value)
{
    //qDebug()<< "#####" << address << "=" << value << " - " << _feedbackAddress;

    if(_feedbackAddress.startsWith(address))
        return DEVICE_ACTION_SWITCH;
    else
        return DEVICE_ACTION_DIM;
}

QString CDimmingx::valueCheck(QString action,QString value)
{
    int svalue = CKnxControl::parseNumberFromString(value);
    if(action == DEVICE_ACTION_DIM)
    {        
        if(svalue>_max)
            svalue = _max;
        if(svalue < _min)
            svalue = _min;

        curent_value = svalue;
        float per = (svalue-_min)/(_max-_min);
        return QString::number(per, 'f', 2);
    }
    else
    {
        if(value == _onValue)
            return DEVICE_STATUS_ON;
        else
            return DEVICE_STATUS_OFF;
    }

}

void CDimmingx::execDeviceAction(QString action, QString value, QString pre_unit)
{
    qDebug() << "CDimming:" << action << "  " << value << " " << pre_unit;

    if(action == DEVICE_ACTION_SWITCH)
    {
        execKnxAction(DEVICE_ACTION_SWITCH,value);
    }
    else if(action == DEVICE_ACTION_DIM)
    {
        float cur_percent = (float)curent_value/230.0;
        //百分比转换为浮点
        value = value.remove("%");
        float precent = (float)((float)parseNumberFromString(value)/100.0);
        if(pre_unit == "=")
        {
            cur_percent = precent;
            execKnxAction(DEVICE_ACTION_DIM,QString::number(cur_percent, 'f', 2));
        }
        else if(pre_unit == "+" )
        {
            cur_percent += precent;            
            execKnxAction(DEVICE_ACTION_DIM,QString::number(cur_percent, 'f', 2));
        }
        else if(pre_unit == "-")
        {
            cur_percent -= precent;
            execKnxAction(DEVICE_ACTION_DIM,QString::number(cur_percent, 'f', 2));
        }
        curent_value = 230*cur_percent;
    }
}
